package com.googlecode.maratische.google.model;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import be.lechtitseb.google.reader.api.core.GoogleReader;
import be.lechtitseb.google.reader.api.model.exception.GoogleReaderException;

import com.googlecode.maratische.google.BaseException;
import com.googlecode.maratische.google.DaoAction;
import com.googlecode.maratische.google.exceptions.AuthenticationException;

public abstract class Command extends Model {
	private static Logger logger = Logger.getLogger(Command.class.getName());
	
	private static Map<Commands, Class<? extends Command>> commands = new HashMap<Commands, Class<? extends Command>>();
	static {
		commands.put(Commands.UpdateMainMenu, CommandUpdateMainMenu.class);
		commands.put(Commands.ReadItem, CommandReadItem.class);
		commands.put(Commands.UpdateFeedOnline, CommandUpdateFeedOnline.class);
		commands.put(Commands.UpdateFeedOffline, CommandUpdateFeedOffline.class);
		commands.put(Commands.UpdateItemMedia, CommandUpdateItemMedia.class);
		commands.put(Commands.RemoveReadedItemMedia, CommandRemoveReadedItemMedia.class);
		commands.put(Commands.UpdateFullItem, CommandUpdateFullItem.class);
		commands.put(Commands.STARRED_ITEM, CommandStarredItem.class);
		commands.put(Commands.UN_STARRED_ITEM, CommandUnStarredItem.class);
		commands.put(Commands.UPDATE_STARRED_ITEMS, CommandUpdateStarredItems.class);
		commands.put(Commands.SearchItemForDelete, CommandSearchItemForDelete.class);
		commands.put(Commands.SearchSpammedItem, CommandSearchSpammedItem.class);
		commands.put(Commands.UpdateBroadcastFriendsItems, CommandUpdateBroadcastFriendsItems.class);
	}
	
	private String type;
	private Integer priority;
	private String string1;
	private String string2;
	private Integer integer1;

	protected Command() {
	}
	
	public static Command createCommand(Commands type) throws BaseException {
		Class<? extends Command> cmdCl = commands.get(type);
		if (cmdCl != null) {
			try {
				return cmdCl.newInstance();
			} catch (InstantiationException e) {
				logger.error(e.getMessage());
				throw new BaseException(e.getMessage());
			} catch (IllegalAccessException e) {
				logger.error(e.getMessage());
				throw new BaseException(e.getMessage());
			}
		}
		return null;
/*		switch (type) {
			case UpdateMainMenu: return new CommandUpdateMainMenu();
			case ReadItem: return new CommandReadItem();
			case UpdateFeedOnline: return new CommandUpdateFeedOnline();
			case UpdateFeedOffline: return new CommandUpdateFeedOffline();
			case UpdateItemMedia: return new CommandUpdateItemMedia();
			case RemoveReadedItemMedia: return new CommandRemoveReadedItemMedia();
			case UpdateFullItem: return new CommandUpdateFullItem();
			case STARRED_ITEM: return new CommandStarredItem();
			case UN_STARRED_ITEM: return new CommandUnStarredItem();
			case UPDATE_STARRED_ITEMS: return new CommandUpdateStarredItems();
			default: return null;
		}*/
	}
	

	protected GoogleReader getGoogleReader(DaoAction daoAction) throws BaseException {
		GoogleReader googleReader = daoAction.getGoogleReader();
		if (googleReader == null) {
			throw new AuthenticationException(null);
		}
		return googleReader;
	}

	public abstract boolean execute(DaoAction daoAction)  throws BaseException, GoogleReaderException, SQLException;
	
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public Integer getPriority() {
		return priority;
	}
	public void setPriority(Integer priority) {
		this.priority = priority;
	}

	public String getString1() {
		if (string1 == null) {
			return "";
		}
		return string1;
	}

	public void setString1(String string1) {
		this.string1 = string1;
	}

	public String getString2() {
		if (string2 == null) {
			return "";
		}
		return string2;
	}

	public void setString2(String string2) {
		this.string2 = string2;
	}

	public Integer getInteger1() {
		if (integer1 == null) {
			return 0;
		}
		return integer1;
	}

	public void setInteger1(Integer integer1) {
		this.integer1 = integer1;
	}
}
